#if !UNITY_WSA_10_0

using OpenCVForUnity.CoreModule;
using OpenCVForUnity.ImgcodecsModule;
using OpenCVForUnity.ImgprocModule;
using OpenCVForUnity.UnityUtils;
using OpenCVForUnity.UnityUtils.Helper;
using OpenCVForUnityExample.DnnModel;
using System;
using System.Collections;
using System.Collections.Generic;
using OpenCVForUnityExample;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
using OpenCVRange = OpenCVForUnity.CoreModule.Range;


    /// <summary>
    /// Pose Estimation MediaPipe Example
    /// An example of using OpenCV dnn module with Human Pose Estimation.
    /// Referring to https://github.com/opencv/opencv_zoo/tree/main/models/pose_estimation_mediapipe
    /// </summary>
    [RequireComponent(typeof(WebCamTextureToMatHelper))]
    public class PoseEstimationRecorder : MonoBehaviour
    {
        /// <summary>
        /// The mask toggle.
        /// </summary>
        public Toggle maskToggle;

        public bool mask;

        [Header("TEST")]

        [TooltipAttribute("Path to test input image.")]
        public string testInputImage;

        /// <summary>
        /// The texture.
        /// </summary>
        Texture2D texture;

        /// <summary>
        /// The webcam texture to mat helper.
        /// </summary>
        WebCamTextureToMatHelper webCamTextureToMatHelper;

        /// <summary>
        /// The bgr mat.
        /// </summary>
        Mat bgrMat;

        /// <summary>
        /// The person detector.
        /// </summary>
        MediaPipePersonDetector personDetector;

        /// <summary>
        /// The pose estimator.
        /// </summary>
        MediaPipePoseEstimator poseEstimator;

        /// <summary>
        /// The FPS monitor.
        /// </summary>
        FpsMonitor fpsMonitor;

        /// <summary>
        /// PERSON_DETECTION_MODEL_FILENAME
        /// </summary>
        protected static readonly string PERSON_DETECTION_MODEL_FILENAME = "OpenCVForUnity/dnn/person_detection_mediapipe_2023mar.onnx";

        /// <summary>
        /// The person detection model filepath.
        /// </summary>
        string person_detection_model_filepath;

        /// <summary>
        /// POSE_ESTIMATION_MODEL_FILENAME
        /// </summary>
        protected static readonly string POSE_ESTIMATION_MODEL_FILENAME = "OpenCVForUnity/dnn/pose_estimation_mediapipe_2023mar.onnx";

        /// <summary>
        /// The pose estimation model filepath.
        /// </summary>
        string pose_estimation_model_filepath;

        public Camera mainCam;

        private RecordController m_RecordController;
        public RecordController recordController
        {
            get
            {
                if (m_RecordController == null)
                    m_RecordController = GetComponentInParent<RecordController>();
                return m_RecordController;
            }
        }

#if UNITY_WEBGL
        IEnumerator getFilePath_Coroutine;
#endif

        // Use this for initialization
        void Start()
        {
            fpsMonitor = GetComponent<FpsMonitor>();

            webCamTextureToMatHelper = gameObject.GetComponent<WebCamTextureToMatHelper>();

            // Update GUI state
            maskToggle.isOn = mask;

#if UNITY_WEBGL
            getFilePath_Coroutine = GetFilePath();
            StartCoroutine(getFilePath_Coroutine);
#else
            person_detection_model_filepath = Utils.getFilePath(PERSON_DETECTION_MODEL_FILENAME);
            pose_estimation_model_filepath = Utils.getFilePath(POSE_ESTIMATION_MODEL_FILENAME);
            Run();
#endif
        }

#if UNITY_WEBGL
        private IEnumerator GetFilePath()
        {
            var getFilePathAsync_0_Coroutine = Utils.getFilePathAsync(PERSON_DETECTION_MODEL_FILENAME, (result) =>
            {
                person_detection_model_filepath = result;
            });
            yield return getFilePathAsync_0_Coroutine;

            var getFilePathAsync_1_Coroutine = Utils.getFilePathAsync(POSE_ESTIMATION_MODEL_FILENAME, (result) =>
            {
                pose_estimation_model_filepath = result;
            });
            yield return getFilePathAsync_1_Coroutine;

            getFilePath_Coroutine = null;

            Run();
        }
#endif

        // Use this for initialization
        void Run()
        {
            //if true, The error log of the Native side OpenCV will be displayed on the Unity Editor Console.
            Utils.setDebugMode(true);
            
            if (string.IsNullOrEmpty(person_detection_model_filepath))
            {
                Debug.LogError(PERSON_DETECTION_MODEL_FILENAME + " is not loaded. Please read “StreamingAssets/OpenCVForUnity/dnn/setup_dnn_module.pdf” to make the necessary setup.");
            }
            else
            {
                personDetector = new MediaPipePersonDetector(person_detection_model_filepath, 0.3f, 0.6f, 5000);// # usually only one person has good performance
            }

            if (string.IsNullOrEmpty(pose_estimation_model_filepath))
            {
                Debug.LogError(POSE_ESTIMATION_MODEL_FILENAME + " is not loaded. Please read “StreamingAssets/OpenCVForUnity/dnn/setup_dnn_module.pdf” to make the necessary setup.");
            }
            else
            {
                poseEstimator = new MediaPipePoseEstimator(pose_estimation_model_filepath, 0.9f);
            }

            if (string.IsNullOrEmpty(testInputImage))
            {
#if UNITY_ANDROID && !UNITY_EDITOR
                // Avoids the front camera low light issue that occurs in only some Android devices (e.g. Google Pixel, Pixel2).
                webCamTextureToMatHelper.avoidAndroidFrontCameraLowLightIssue = true;
#endif
                webCamTextureToMatHelper.Initialize();
            }
            else
            {
                /////////////////////
                // TEST

                var getFilePathAsync_0_Coroutine = Utils.getFilePathAsync("OpenCVForUnity/dnn/" + testInputImage, (result) =>
                {
                    string test_input_image_filepath = result;
                    if (string.IsNullOrEmpty(test_input_image_filepath)) Debug.Log("The file:" + testInputImage + " did not exist in the folder “Assets/StreamingAssets/OpenCVForUnity/dnn”.");

                    Mat img = Imgcodecs.imread(test_input_image_filepath);
                    if (img.empty())
                    {
                        img = new Mat(424, 640, CvType.CV_8UC3, new Scalar(0, 0, 0));
                        Imgproc.putText(img, testInputImage + " is not loaded.", new Point(5, img.rows() - 30), Imgproc.FONT_HERSHEY_SIMPLEX, 0.7, new Scalar(255, 255, 255, 255), 2, Imgproc.LINE_AA, false);
                        Imgproc.putText(img, "Please read console message.", new Point(5, img.rows() - 10), Imgproc.FONT_HERSHEY_SIMPLEX, 0.7, new Scalar(255, 255, 255, 255), 2, Imgproc.LINE_AA, false);
                    }
                    else
                    {
                        TickMeter tm = new TickMeter();
                        tm.start();

                        Mat persons = personDetector.infer(img);

                        tm.stop();
                        Debug.Log("MediaPipePersonDetector Inference time (preprocess + infer + postprocess), ms: " + tm.getTimeMilli());

                        // Estimate the pose of each person
                        for (int i = 0; i < persons.rows(); ++i)
                        {
                            tm.reset();
                            tm.start();

                            // pose estimator inference
                            List<Mat> results = poseEstimator.infer(img, persons.row(i), mask);

                            tm.stop();
                            Debug.Log("MediaPipePoseEstimator Inference time (preprocess + infer + postprocess), ms: " + tm.getTimeMilli());
                            
                            if (!results[1].empty())
                                poseEstimator.visualize_mask(img, results[1], false);

                            poseEstimator.visualize(img, results[0], true, false);
                        }

                        //personDetector.visualize(img, persons, true, false);
                    }

                    gameObject.transform.localScale = new Vector3(img.width(), img.height(), 1);
                    float imageWidth = img.width();
                    float imageHeight = img.height();
                    float widthScale = (float)Screen.width / imageWidth;
                    float heightScale = (float)Screen.height / imageHeight;
                    if (widthScale < heightScale)
                    {
                        mainCam.orthographicSize = (imageWidth * (float)Screen.height / (float)Screen.width) / 2;
                    }
                    else
                    {
                        mainCam.orthographicSize = imageHeight / 2;
                    }
                    
                    Imgproc.cvtColor(img, img, Imgproc.COLOR_BGR2RGB);
                    Texture2D texture = new Texture2D(img.cols(), img.rows(), TextureFormat.RGB24, false);
                    Utils.matToTexture2D(img, texture);
                    gameObject.GetComponent<Renderer>().material.mainTexture = texture;
                });
                StartCoroutine(getFilePathAsync_0_Coroutine);

                /////////////////////
            }
        }

        /// <summary>
        /// Raises the webcam texture to mat helper initialized event.
        /// </summary>
        public void OnWebCamTextureToMatHelperInitialized()
        {
            Debug.Log("OnWebCamTextureToMatHelperInitialized");

            Mat webCamTextureMat = webCamTextureToMatHelper.GetMat();

            texture = new Texture2D(webCamTextureMat.cols(), webCamTextureMat.rows(), TextureFormat.RGBA32, false);
            Utils.matToTexture2D(webCamTextureMat, texture);

            gameObject.GetComponent<Renderer>().material.mainTexture = texture;

            gameObject.transform.localScale = new Vector3(webCamTextureMat.cols(), webCamTextureMat.rows(), 1);
            Debug.Log("Screen.width " + Screen.width + " Screen.height " + Screen.height + " Screen.orientation " + Screen.orientation);

            if (fpsMonitor != null)
            {
                fpsMonitor.Add("width", webCamTextureMat.width().ToString());
                fpsMonitor.Add("height", webCamTextureMat.height().ToString());
                fpsMonitor.Add("orientation", Screen.orientation.ToString());
            }


            float width = webCamTextureMat.width();
            float height = webCamTextureMat.height();

            float widthScale = (float)Screen.width / width;
            float heightScale = (float)Screen.height / height;
            if (widthScale < heightScale)
            {
                mainCam.orthographicSize = (width * (float)Screen.height / (float)Screen.width) / 2;
            }
            else
            {
                mainCam.orthographicSize = height / 2;
            }

            bgrMat = new Mat(webCamTextureMat.rows(), webCamTextureMat.cols(), CvType.CV_8UC3);

            m_BeginTime = Time.time;
        }

        /// <summary>
        /// Raises the webcam texture to mat helper disposed event.
        /// </summary>
        public void OnWebCamTextureToMatHelperDisposed()
        {
            Debug.Log("OnWebCamTextureToMatHelperDisposed");

            if (bgrMat != null)
                bgrMat.Dispose();

            if (texture != null)
            {
                Texture2D.Destroy(texture);
                texture = null;
            }
        }

        /// <summary>
        /// Raises the webcam texture to mat helper error occurred event.
        /// </summary>
        /// <param name="errorCode">Error code.</param>
        public void OnWebCamTextureToMatHelperErrorOccurred(WebCamTextureToMatHelper.ErrorCode errorCode)
        {
            Debug.Log("OnWebCamTextureToMatHelperErrorOccurred " + errorCode);
        }

        private Texture2D frontTex;
        private Texture2D sideTex;
        private bool m_recording = true;
        public bool recording => m_recording;
        private int goodFrameCount;
        public Action<Texture2D> onRecordFrontTexEnd;
        public Action<Texture2D, Texture2D> onRecordedEnd;

        //private float m_RecordedFrontTexTime;
        // Update is called once per frame
        void Update()
        {
            if (!m_recording)
                return;

            
            if (webCamTextureToMatHelper.IsPlaying() && webCamTextureToMatHelper.DidUpdateThisFrame())
            {
                Mat rgbaMat = webCamTextureToMatHelper.GetMat();

                if (personDetector == null || poseEstimator == null)
                {
                    Imgproc.putText(rgbaMat, "model file is not loaded.", new Point(5, rgbaMat.rows() - 30), Imgproc.FONT_HERSHEY_SIMPLEX, 0.7, new Scalar(255, 255, 255, 255), 2, Imgproc.LINE_AA, false);
                    Imgproc.putText(rgbaMat, "Please read console message.", new Point(5, rgbaMat.rows() - 10), Imgproc.FONT_HERSHEY_SIMPLEX, 0.7, new Scalar(255, 255, 255, 255), 2, Imgproc.LINE_AA, false);
                }
                else
                {
                    Imgproc.cvtColor(rgbaMat, bgrMat, Imgproc.COLOR_RGBA2BGR);

                    bool gyroOK = true;
                    if(Application.platform != RuntimePlatform.WindowsEditor && Application.platform != RuntimePlatform.OSXEditor)
                    {
                        gyroOK = recordController.gyroOK;
                    }

                    if (gyroOK)
                    {
                        Mat persons = personDetector.infer(bgrMat);

                        // Estimate the pose of each person
                        for (int i = 0; i < persons.rows(); ++i)
                        {
                            //tm.reset();
                            //tm.start();

                            // pose estimator inference
                            List<Mat> results = poseEstimator.infer(bgrMat, persons.row(i), mask);

                            //tm.stop();
                            //Debug.Log("MediaPipePoseEstimator Inference time (preprocess + infer + postprocess), ms: " + tm.getTimeMilli());

                            if (!results[1].empty())
                                poseEstimator.visualize_mask(bgrMat, results[1], false, false);

                            poseEstimator.visualize(bgrMat, results[0], false, false);

                            var outlineMat = results[1];
                            var poseMat = results[0];
                            if (poseMat.empty() || poseMat.rows() < 317)
                            {
                                //Debug.Log($"error pose mat rows:{poseMat.rows()}");
                            }
                            else
                            {
                                if (frontTex == null && Time.time - m_BeginTime > 5)
                                {
                                    if (CheckFrontPoseGood(outlineMat, poseMat))
                                    {
                                        goodFrameCount++;
                                        if (goodFrameCount > webCamTextureToMatHelper.requestedFPS)
                                        {
                                            goodFrameCount = 0;
                                            Debug.Log($"good front pose:{poseMat.rows()}");
                                            Utils.matToTexture2D(rgbaMat, texture);
                                            this.frontTex = texture;
                                            
                                            onRecordFrontTexEnd?.Invoke(frontTex);
                                            AudioController.instance.PlayBattleSound("正面完成", transform.position);
                                            //m_RecordedFrontTexTime = Time.time;
                                            
                                            OnWebCamTextureToMatHelperInitialized();
                                            
                                            DoActionDelay.DelayAction(2, () =>
                                            {
                                                AudioController.instance.PlayBattleSound("请向左转身", transform.position);
                                            });
                                        }
                                    }
                                }
                                else if (sideTex == null && Time.time - m_BeginTime > 5)
                                {
                                    if (CheckSidePoseGood(outlineMat, poseMat))
                                    {
                                        goodFrameCount++;
                                        if (goodFrameCount > webCamTextureToMatHelper.requestedFPS)
                                        {
                                            goodFrameCount = 0;
                                            Debug.Log($"good side pose:{poseMat.rows()}");
                                            m_recording = false;
                                            Utils.matToTexture2D(rgbaMat, texture);

                                            this.sideTex = texture;

                                            var callback = onRecordedEnd;
                                            callback?.Invoke(frontTex, sideTex);
                                            onRecordedEnd = null;
                                            
                                            AudioController.instance.PlayBattleSound("拍照完成", transform.position);
                                            return;
                                        }
                                    }
                                }
                            }
                        }

                        //personDetector.visualize(bgrMat, persons, false, false);
                    }
                }

                Imgproc.cvtColor(bgrMat, rgbaMat, Imgproc.COLOR_BGR2RGBA);

                Utils.matToTexture2D(rgbaMat, texture);
            }

        }

        private float m_BeginTime;
        private float m_LastPlayAdjustPoseAudioTime;

        bool CheckFrontPoseGood(Mat outlineMat, Mat poseMat)
        {
            int height = outlineMat.rows();
            int auxiliary_points_num = 6;
            Mat results_col4_199_39x5 = poseMat.rowRange(new OpenCVRange(4, 199 - (5 * auxiliary_points_num)))
                .reshape(1, 39 - auxiliary_points_num);

            float[] landmarks_screen_xyz = new float[(39 - auxiliary_points_num) * 3];
            results_col4_199_39x5.colRange(new OpenCVRange(0, 3)).get(0, 0, landmarks_screen_xyz);

            // # only show visible keypoints which presence bigger than 0.8
            float[] landmarks_presence = new float[(39 - auxiliary_points_num)];
            results_col4_199_39x5.colRange(new OpenCVRange(4, 5)).get(0, 0, landmarks_presence);

            //draw pose key points
            int leftShoulderPoint = 11;
            int rightShoulderPoint = 12;
            int leftWristPoint = 15;
            int rightWristPoint = 16;
            int leftThighPoint = 23;
            int leftFootPoint = 29;
            int rightThighPoint = 24;
            int rightFootPoint = 30;

            Vector2 leftShoulderPos = Vector2.zero;
            Vector2 rightShoulderPos = Vector2.zero;
            Vector2 leftWristPos = Vector2.zero;
            Vector2 rightWristPos = Vector2.zero;
            Vector2 leftThighPos = Vector2.zero;
            Vector2 rightThighPos = Vector2.zero;
            Vector2 leftFootPos = Vector2.zero;
            Vector2 rightFootPos = Vector2.zero;
            for (int j = 0; j < landmarks_screen_xyz.Length / 3; ++j)
            {
                int idx = j * 3;
                if (landmarks_presence[j] > 0.8)
                {
                    var pos = new Vector2(landmarks_screen_xyz[idx], height - landmarks_screen_xyz[idx + 1] - 1);
                    if (j == leftShoulderPoint) leftShoulderPos = pos;
                    if (j == rightShoulderPoint) rightShoulderPos = pos;
                    if (j == leftWristPoint) leftWristPos = pos;
                    if (j == rightWristPoint) rightWristPos = pos;
                    if (j == leftThighPoint) leftThighPos = pos;
                    if (j == leftFootPoint) leftFootPos = pos;
                    if (j == rightThighPoint) rightThighPos = pos;
                    if (j == rightFootPoint) rightFootPos = pos;
                }
            }

            Vector2 shoulderPos = (leftShoulderPos + rightShoulderPos) / 2;
            Vector2 hipPos = (leftThighPos + rightThighPos) / 2;
            Vector2 footPos = (leftFootPos + rightFootPos) / 2;
            bool footOk = Mathf.Abs(hipPos.y - footPos.y) > Mathf.Abs(shoulderPos.y - hipPos.y);
            float wristDis = leftWristPos.x - rightWristPos.x;
            float shoulderDis = leftShoulderPos.x - rightShoulderPos.x;
            bool armOK = wristDis > shoulderDis * 2.2f;
            if (footOk && armOK)
            {
                return true;
            }
            else
            {
                if (footOk)
                {
                    //Debug.Log($"wrist dis:{wristDis}   shoulder dis:{shoulderDis} ");
                }
                else
                {
                    if (Time.time - m_BeginTime > 8)
                    {
                        if (Time.time - m_LastPlayAdjustPoseAudioTime > 5)
                        {
                            m_LastPlayAdjustPoseAudioTime = Time.time;
                            AudioController.instance.PlayBattleSound("请远离镜头", transform.position);
                        }
                    }
                }
                return false;
            }
        }
        bool CheckSidePoseGood(Mat outlineMat, Mat poseMat)
        {
            int height = outlineMat.rows();
            int auxiliary_points_num = 6;
            Mat results_col4_199_39x5 = poseMat.rowRange(new OpenCVRange(4, 199 - (5 * auxiliary_points_num)))
                .reshape(1, 39 - auxiliary_points_num);

            float[] landmarks_screen_xyz = new float[(39 - auxiliary_points_num) * 3];
            results_col4_199_39x5.colRange(new OpenCVRange(0, 3)).get(0, 0, landmarks_screen_xyz);

            // # only show visible keypoints which presence bigger than 0.8
            float[] landmarks_presence = new float[(39 - auxiliary_points_num)];
            results_col4_199_39x5.colRange(new OpenCVRange(4, 5)).get(0, 0, landmarks_presence);

            //draw pose key points
            int leftShoulderPoint = 11;
            int rightShoulderPoint = 12;
            int leftElbowPoint = 13;
            int rightElbowPoint = 14;
            int leftThighPoint = 23;
            int leftFootPoint = 29;
            int rightThighPoint = 24;
            int rightFootPoint = 30;

            Vector2 leftShoulderPos = Vector2.zero;
            Vector2 rightShoulderPos = Vector2.zero;
            Vector2 leftElbowPos = Vector2.zero;
            Vector2 rightElbowPos = Vector2.zero;
            Vector2 leftThighPos = Vector2.zero;
            Vector2 rightThighPos = Vector2.zero;
            Vector2 leftFootPos = Vector2.zero;
            Vector2 rightFootPos = Vector2.zero;
            for (int j = 0; j < landmarks_screen_xyz.Length / 3; ++j)
            {
                int idx = j * 3;
                if (landmarks_presence[j] > 0.8)
                {
                    var pos = new Vector2(landmarks_screen_xyz[idx], height - landmarks_screen_xyz[idx + 1] - 1);
                    if (j == leftShoulderPoint) leftShoulderPos = pos;
                    if (j == rightShoulderPoint) rightShoulderPos = pos;
                    //if (j == leftElbowPoint) leftElbowPos = pos;
                    if (j == rightElbowPoint) rightElbowPos = pos;
                    if (j == leftThighPoint) leftThighPos = pos;
                    if (j == leftFootPoint) leftFootPos = pos;
                    if (j == rightThighPoint) rightThighPos = pos;
                    if (j == rightFootPoint) rightFootPos = pos;
                }
            }

            Vector2 shoulderPos = (leftShoulderPos + rightShoulderPos) / 2;
            Vector2 hipPos = (leftThighPos + rightThighPos) / 2;
            Vector2 footPos = (leftFootPos + rightFootPos) / 2;

            bool footOk = Mathf.Abs(hipPos.y - footPos.y) > Mathf.Abs(shoulderPos.y - hipPos.y);
            float shouldDis = Mathf.Abs(leftShoulderPos.x - rightShoulderPos.x);
            float halfArmDis =  (rightShoulderPos - rightElbowPos).magnitude/ 2;
            bool sideOK = shouldDis < halfArmDis;
                         
            if (footOk && sideOK)
            {
                //Debug.Log($"side pose ok");
                return true;
            }
            else
            {
                if (footOk)
                {
                    Debug.Log($"shoulderDis:{halfArmDis}  ");
                }
                else
                {
                    if (Time.time - m_BeginTime > 8)
                    {
                        if (Time.time - m_LastPlayAdjustPoseAudioTime > 5)
                        {
                            m_LastPlayAdjustPoseAudioTime = Time.time;
                            AudioController.instance.PlayBattleSound("请远离镜头", transform.position);
                        }
                    }
                }
                return false;
            }
        }
        /// <summary>
        /// Raises the destroy event.
        /// </summary>
        void OnDestroy()
        {
            if(webCamTextureToMatHelper != null)
                webCamTextureToMatHelper.Dispose();

            if (personDetector != null)
                personDetector.dispose();

            if (poseEstimator != null)
                poseEstimator.dispose();

            Utils.setDebugMode(false);

#if UNITY_WEBGL
            if (getFilePath_Coroutine != null)
            {
                StopCoroutine(getFilePath_Coroutine);
                ((IDisposable)getFilePath_Coroutine).Dispose();
            }
#endif
        }

        /// <summary>
        /// Raises the back button click event.
        /// </summary>
        public void OnBackButtonClick()
        {
            SceneManager.LoadScene("OpenCVForUnityExample");
        }

        /// <summary>
        /// Raises the play button click event.
        /// </summary>
        public void OnPlayButtonClick()
        {
            webCamTextureToMatHelper.Play();
        }

        /// <summary>
        /// Raises the pause button click event.
        /// </summary>
        public void OnPauseButtonClick()
        {
            webCamTextureToMatHelper.Pause();
        }

        /// <summary>
        /// Raises the stop button click event.
        /// </summary>
        public void OnStopButtonClick()
        {
            webCamTextureToMatHelper.Stop();
        }

        /// <summary>
        /// Raises the change camera button click event.
        /// </summary>
        public void OnChangeCameraButtonClick()
        {
            webCamTextureToMatHelper.requestedIsFrontFacing = !webCamTextureToMatHelper.requestedIsFrontFacing;
        }

        /// <summary>
        /// Raises the mask toggle value changed event.
        /// </summary>
        public void OnMaskToggleValueChanged()
        {
            if (maskToggle.isOn != mask)
            {
                mask = maskToggle.isOn;
            }
        }

        public void Reset()
        {
            if(this.frontTex)
                DestroyImmediate(frontTex);
            this.frontTex = null;
            if(this.sideTex)
                DestroyImmediate(sideTex);
            this.sideTex = null;

            if (!m_recording)
            {
                m_recording = true;
                OnWebCamTextureToMatHelperInitialized();
            }
        }
    }


#endif